package com.gqr.lock.reentrantlock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Copyright (C), 2020-2024,gqr
 * FileName:Upgrading
 * author:guqingrong
 * Date:2024-05-13 21:15
 * Description:
 * History:
 * <author>    <time>    <version>    <desc>
 * 作者姓名     修改时间     版本号        描述
 */
public class Upgrading {
    private static ReentrantReadWriteLock reentrantReadWriteLock =
            new ReentrantReadWriteLock(false);

    // 读锁
    private static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();

    // 写锁
    private static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();

    private static void readUpgrading() {
        readLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "得到了读锁,正在读取");
            Thread.sleep(1000);
            System.out.println("升级不会带来成功带来阻塞");
            writeLock.lock();
            System.out.println(Thread.currentThread().getName() +"升级成功获取到了写锁");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + "释放了读锁");
            readLock.unlock();
        }
    }

    private static void writeDowngrading() {
        writeLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "得到了写锁，正在写入");
            Thread.sleep(1000);
            readLock.lock();

            System.out.println(Thread.currentThread().getName() + "在不释放写锁的情况下,直接获取读锁,成功降级");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
            System.out.println(Thread.currentThread().getName() + "释放了写锁");
            writeLock.unlock();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        // 先演示降级是可以的
//        System.out.println("演示降级是可以的");
//        Thread thread1 = new Thread(() -> writeDowngrading(), "Thread1");
//        thread1.start();
//        thread1.join();
        System.out.println("---------------------");
        System.out.println("演示升级是不可以的");
        new Thread(()->readUpgrading(),"Thread2").start();
    }
}
